package excelUtil

import (
	"errors"
	"fmt"
	"github.com/xuri/excelize/v2"
	"go-api-template/internal/util/stringUtil"
	"go-api-template/service"
	"reflect"
	"strconv"
	"time"
)

func Generate(data []interface{}, sheet string, filePath string) (err error) {
	f := excelize.NewFile()
	f.DeleteSheet("Sheet1")
	f.NewSheet(sheet)
	f.SetActiveSheet(f.GetSheetIndex(sheet))

	// 记录最大字符长度
	maxFiledLengthList := make([]int, len(data))

	columnG := 0
	// 行处理
	for row, item := range data {
		t := reflect.TypeOf(item)
		v := reflect.ValueOf(item)
		k := t.Kind()
		if k == reflect.Struct {
			column := 1
			// 列处理
			for i := 0; i < v.NumField(); i++ {
				if head := t.Field(i).Tag.Get("excel"); head != "" {
					// 字段长
					var l int

					// 写入值(根据类型)
					axis := fmt.Sprintf("%s%d", stringUtil.GetAToAZ(column), row+2)

					// 基础类型处理
					switch v.Field(i).Kind() {
					case reflect.String:
						// 去除富文本格式
						_ = f.SetCellStr(sheet, axis, stringUtil.TrimHtml(v.Field(i).String()))
						l = v.Field(i).Len()
					case reflect.Int:
						_ = f.SetCellInt(sheet, axis, int(v.Field(i).Int()))
						l = len(strconv.FormatInt(v.Field(i).Int(), 10))
					case reflect.Float64:
						_ = f.SetCellStr(sheet, axis, fmt.Sprintf("%0.2f", v.Field(i).Float()))
					default:
						// 私有类型处理
						switch v.Field(i).Type().String() {
						case "time.Time":
							_ = f.SetCellStr(sheet, axis, func() string {
								t := v.Field(i).Interface().(time.Time)
								if t.IsZero() {
									return ""
								} else {
									return t.Format("2006-01-02 15:04:05")
								}
							}())
						}
					}

					// 比较设置最大长
					if maxFiledLengthList[column] < l {
						maxFiledLengthList[column] = l
					}

					// 写入表头
					if row == 0 {

						// 优先使用表头宽
						headLength := len(head)
						if maxFiledLengthList[column] < headLength {
							maxFiledLengthList[column] = headLength
						}
						_ = f.SetCellValue(sheet, fmt.Sprintf("%s%d", stringUtil.GetAToAZ(column), row+1), head)
					}

					column++
				}
			}

			columnG = column
		} else {
			err = errors.New("仅支持Struct类型")
		}

	}

	if len(data) == 0 {
		f.SetCellValue(sheet, "A1", "空数据")
	} else {
		// 添加自动过滤器
		t := reflect.TypeOf(data[0])
		f.AutoFilter(sheet, "A1", fmt.Sprintf("%s%d", stringUtil.GetAToAZ(t.NumField()-1), 1), "")

		// 设置动态列宽
		for i := 1; i <= columnG; i++ {
			cs := maxFiledLengthList[i]
			if cs >= 255 {
				cs = 255
			}
			columnWidth := float64(cs)
			startCol := stringUtil.GetAToAZ(i)

			err = f.SetColWidth(sheet, startCol, startCol, columnWidth)
			if err != nil {
				service.Log.Error(err.Error())
			}
		}
	}

	err = f.SaveAs(filePath)
	return
}
